// 装饰器 @+函数名字（或者返回的是一个函数）
// 随着TypeScript和ES6里引入了类，在一些场景下我们需要额外的特性来支持标注或修改类及其成员。 装饰器（Decorators）为我们在类的声明及成员上通过元编程语法添加标注提供了一种方式。 Javascript里的装饰器目前处在 建议征集的第二阶段，但在TypeScript里已做为一项实验性特性予以支持。
// 装饰器是一种特殊类型的声明，它能够被附加到类声明，方法， 访问符，属性或参数上。 装饰器使用 @expression这种形式，expression求值后必须为一个函数，它会在运行时被调用，被装饰的声明信息做为参数传入。


// function setName() {
//   console.log('get setName');
//   return (target: any) => {
//       console.log('setName');      
//   }  
// }

// function setAge() {
//   console.log('get setAge');
//   return (target: any) => {
//     console.log('setAge');
    
//   }
// }

// @setName()
// @setAge()
// class ClassDec {
  
// }

// let sign = null
// function setName(name: string) {
//   return (target: new() => any) => {
//     sign = target
//     console.log(target.name)    
//   }
// }

// @setName('lison')
// class ClassDes {
//   constructor(){}
// }
// console.log(sign === ClassDes);
// console.log(sign === ClassDes.prototype.constructor);

// function addName(constructor: new() => any) {
//   constructor.protorype.name = 'lison'
// }
// @addName
// class ClassD {}
// interface ClassD {
//   name: string;
// }
// const d = new ClassD()
// console.log(d.name);

// function classDecorator<T extends {new(...args:any[]):{}}>(constructor:T) {
//   return class extends constructor {
//       newProperty = "new property";
//       hello = "override";
//   }
// }

// @classDecorator
// class Greeter {
//   property = "property";
//   hello: string;
//   constructor(m: string) {
//       this.hello = m;
//   }
// }

// console.log(new Greeter("world"));


interface ObjWithAnyKeys {
  [kye: string]: any
}

let obj12: ObjWithAnyKeys = {}
Object.defineProperty(obj12, 'name', {
  value: 'lison',
  writable: false,  // 是否可以修改属性值
  configurable: false,  // 是否可以修改属性
  enumerable: true   // 可枚举
})

console.log(obj12.name);
